/*
 * sgc_hash.h
 *
 *  Created on: 2011-7-5
 *      Author: rendong
 */

#ifndef SGC_HASH_H_
#define SGC_HASH_H_

// hash 节点
typedef struct _sgc_hash_table_item_s sgc_hash_table_item_t;

struct _sgc_hash_table_item_s
{
	char *key;
	void *value;
	unsigned long hash;
	sgc_hash_table_item_t *next;
};

// hash table 结构
typedef struct _sgc_hash_table_s
{
	sgc_hash_table_item_t ** items;
	size_t nlimit;
	size_t size;
} sgc_hash_table_t;

/**
 * 初始化hash table
 */
void sgc_hash_init(sgc_hash_table_t * hashtable, size_t capacity);
/**
 * 向hash表中加入数据
 * @return 键存在，返回1， 否则返回0
 */
int sgc_hash_put(sgc_hash_table_t * hashtable, char *key, void *value);
/**
 * 获取数据
 */
void* sgc_hash_get(sgc_hash_table_t * hashtable, char *key);
/**
 * 删除
 */
void sgc_hash_del(sgc_hash_table_t * hashtable, char *key);

/**
 * hash 33 算法 来自php代码
 */
static inline unsigned long sgc_inline_hash_func(const char *key, size_t nkey)
{
	register unsigned long hash = 5381;

	/* variant with the hash unrolled eight times */
	for (; nkey >= 8; nkey -= 8) {
		hash = ((hash << 5) + hash) + *key++;
		hash = ((hash << 5) + hash) + *key++;
		hash = ((hash << 5) + hash) + *key++;
		hash = ((hash << 5) + hash) + *key++;
		hash = ((hash << 5) + hash) + *key++;
		hash = ((hash << 5) + hash) + *key++;
		hash = ((hash << 5) + hash) + *key++;
		hash = ((hash << 5) + hash) + *key++;
	}

	switch (nkey) {
		case 7: hash = ((hash << 5) + hash) + *key++; /* fall through... */
		case 6: hash = ((hash << 5) + hash) + *key++; /* fall through... */
		case 5: hash = ((hash << 5) + hash) + *key++; /* fall through... */
		case 4: hash = ((hash << 5) + hash) + *key++; /* fall through... */
		case 3: hash = ((hash << 5) + hash) + *key++; /* fall through... */
		case 2: hash = ((hash << 5) + hash) + *key++; /* fall through... */
		case 1: hash = ((hash << 5) + hash) + *key++; break;
		case 0: break;
	}

	return hash;
}

#endif /* SGC_HASH_H_ */
